#ifndef CVX_MATCH_H
#define CVX_MATCH_H 1

#include "cvxImage.h"

class CvxMatch
{
public:
	CvxMatch(int threshold = 50, int desireNumber = 150, int verticalMax = 10);
	~CvxMatch();

	void configure(int threshold, int matchNumber);
	bool particalMatch(const Mat &imageA, const Mat &imageB, vector<Point2f> &ptA, vector<Point2f> &ptB, 
					   const cv::Rect &roi);
	bool match(const Mat &imageA, const Mat &imageB, vector<Point2f> &ptA, vector<Point2f> &ptB);


	//fast match using FAST, BRIEF, zncc and box constraint 
	static bool fastMatch(const Mat &imageA, const Mat &imageB, vector<Point2f> &ptA, vector<Point2f> &ptB, 
						  const int maxVDisparity = 5);

	//sift match in the left and right image, and may check the planar constraint (homography mapping)
	static bool SIFTmatch(const Mat &imageA, const Mat &imageB, vector<Point2f> &ptA, vector<Point2f> &ptB, bool inAPlane); 



	//match feature point using zncc
	/************************************************************************/
	/*	
		img1, img2: gray image
		v_d_th: vertical disparity threshold, maximum vertical disparity
		zncc_th: zncc threshold
		w_len : length of edge of window 11*11 7*7 ...
	*/
	/************************************************************************/
	static bool zncc(const vector<KeyPoint> &kps1, const vector<KeyPoint> &kps2, 
					 const Mat &img1, const Mat &img2, int v_disparity_th, float zncc_th,
					 int w_len, vector<DMatch> &matches);

	/************************************************************************/
	/* 
		haimming distance match with in a vertical threshold
		kps1: keypoints 1
		kps2:
		dsp1: description of keypoints 1
		dsp2:
		v_th: vertical distance threshold 
		height: maxinum height
	*/
	/************************************************************************/
	static bool haimmingMatch(const vector<KeyPoint> &kps1, const vector<KeyPoint> &kps2, 
					const Mat &dsp1, const Mat &dsp2, const unsigned int v_th, const int height, vector<DMatch> &matches);

	static bool SIFTMatch();
	
	//find homography inlier by the threshold
	static bool findHomographyInliner(vector<Point2f> &ptA, vector<Point2f> &ptB, int reprojThreshold);

	//only for test
	static bool showMatchedImage(const Mat &leftImage, const Mat &rightImage, const vector<Point2f> &ptA, const vector<Point2f> &ptB);

private:
	FastFeatureDetector        *m_pFast;
	GridAdaptedFeatureDetector *m_pDetector;
	BriefDescriptorExtractor   *m_pExtractor;
	BFMatcher                  *m_pMatcher;
	int m_threshold;           /*increase or decrease threshold*/
	int m_desiredNumber;       /*match   number*/
	int m_verticalDispartyMax; /*vertical disparity threshold*/ 	

private:
	void tooFew();
	void tooMany();

};

#endif